/*LICENSE_BEGIN
 * ******************************************************************
 * Copyright 2006 by the Dainamite Robocup-Team at the
 * DAI-Labor, TU-Berlin (www.dai-labor.de)
 * 
 * Members of Dainamite are:
 * Holger Endert
 * Robert Wetzker
 * Thomas Karbe
 * Axel Heßler
 * Philippe Bütter
 * Felix Brossmann
 * 
 * Licensed under the GNU GPL (General Public License) Free Software 
 * License, Version 2. You may use this file only in compliance with 
 * the License. You may obtain a copy of the License at:
 * 
 * http://www.fsf.org/licensing/licenses/gpl.txt
 * ******************************************************************
LICENSE_END*/
/* Generated By:JavaCC: Do not edit this line. RobocupClientParser.java */
                                   // Robocup Message Parser
package robocup.parser9;

// Subsequent Parsers
import robocup.component.infotypes.Info;
import robocup.component.RobocupAgent;
import java.io.StringReader;


/**
 * The Parser for RobocupAgents. It contains all needed parsers for the 
 * different message types. It is developed to parse Messages from the 
 * SoccerServer version 9.45. This class is created by the
 * javacc parser generator. Therefore do not change this class directly,
 * but change the RobocupClientParser.jj and regenerate the code afterwards.
 */
public class RobocupClientParser extends RobocupParser implements RobocupClientParserConstants {

        /**
	 * A reference to the RobocupAgent, which contains the parser.
	 */
        RobocupAgent ra;

        /**
	 * The command to parse.
	 */
        String cmd;

        /**
	 * The SenseBodyParser.
	 */
        SenseBodyParser sbp;

        /**
	 * The SeeParser.
	 */
        SeeParser sp;

        /**
	 * The HearParser.
	 */
        HearParser hp;

        /**
	 * The ParamParser.
	 */
        ParamParser pp;

        /**
	 * The Parser for remaining messages.
	 */
        OtherParser op;

        /**
	 * The arrival time of the message.
	 */
        long arrivalTime = -1;

        /**
	 * The info to return.
	 */
        Info info = null;

        /**
	 * Creates a new instance of the parser.
	 * @param - StringReader - reader for accessing strings
	 * @param - RobocupAgent - the agent object containing this parser
	 */
        public RobocupClientParser(StringReader str, RobocupAgent ra) {
                this(str);
                this.ra = ra;

                sbp = new SenseBodyParser(new StringReader(""), ra);
                sp = new SeeParser(new StringReader(""), ra);
                hp = new HearParser(new StringReader(""), ra);
                pp = new ParamParser(new StringReader(""), ra);
                op = new OtherParser(new StringReader(""), ra);
        }

        /**
	 * This method evaluates, which of the corresponding sub-parsers should
	 * be used for the given message.
	 * @return the corresponding info-object of the received message.
	 */
    public Info parseCommand (String cmd)
        throws ParseException{
      arrivalTime = System.nanoTime();
      ReInit(new StringReader(cmd));
        this.cmd = cmd;

      info = null;
      try {
        evalMessageType();
      } catch (ParseException e) {
        System.out.println("Exception during Parsing with Command:");
        System.out.println("  " + cmd +"\r\n"+ e);
      }
      if(info != null){
          info.setArrivalTime(arrivalTime);
      }
      return info;
    }

/**
 * The sense method tries to check if "sense_body","see","hear" or "other" message was received.
 * It then calls the specific parser.
 */
  final public void evalMessageType() throws ParseException {
    jj_consume_token(OB);
    switch (jj_nt.kind) {
    case SEP:
      jj_consume_token(SEP);
      break;
    default:
      jj_la1[0] = jj_gen;
      ;
    }
    switch (jj_nt.kind) {
    case SENSEBODY:
      sense_body();
      break;
    case SEE:
      see();
      break;
    case HEAR:
      hear();
      break;
    case SERVER_PARAM:
    case PLAYER_PARAM:
    case PLAYER_TYPE:
      param();
      break;
    case CHANGE_PLAYER_TYPE:
      clang();
      break;
    case SCORE:
    case INIT:
    case OK:
    case ERROR:
    case RECONNECT:
      other();
      break;
    case CHR:
      unknown();
      break;
    default:
      jj_la1[1] = jj_gen;
      jj_consume_token(-1);
      throw new ParseException();
    }
  }

  final public void sense_body() throws ParseException {
    jj_consume_token(SENSEBODY);
    jj_consume_token(SEP);
         info = sbp.parseSenseBody(cmd.substring(12, cmd.length()-1));
  }

  final public void see() throws ParseException {
    jj_consume_token(SEE);
    jj_consume_token(SEP);
         info = sp.parseSee(cmd.substring(5, cmd.length()-1));
  }

  final public void hear() throws ParseException {
    jj_consume_token(HEAR);
    jj_consume_token(SEP);
         info = hp.parseHear(cmd.substring(6, cmd.length()-1));
  }

  final public void param() throws ParseException {
    switch (jj_nt.kind) {
    case SERVER_PARAM:
      jj_consume_token(SERVER_PARAM);
                               info = pp.parseServerParam(cmd.substring(14, cmd.length()-1));
      break;
    case PLAYER_PARAM:
      jj_consume_token(PLAYER_PARAM);
                               info = pp.parsePlayerParam(cmd.substring(14, cmd.length()-1));
      break;
    case PLAYER_TYPE:
      jj_consume_token(PLAYER_TYPE);
                              info = pp.parsePlayerType(cmd.substring(13, cmd.length()-1));
      break;
    default:
      jj_la1[2] = jj_gen;
      jj_consume_token(-1);
      throw new ParseException();
    }
  }

  final public void clang() throws ParseException {
    jj_consume_token(CHANGE_PLAYER_TYPE);
                                     info = op.parseChangeType(cmd.substring(20, cmd.length()-1));
  }

  final public void other() throws ParseException {
    switch (jj_nt.kind) {
    case INIT:
      jj_consume_token(INIT);
                       info = hp.parseInit(cmd.substring(6, cmd.length()-1));
      break;
    case RECONNECT:
      jj_consume_token(RECONNECT);
                            info = hp.parseReconnect(cmd.substring(11, cmd.length()-1));
      break;
    case ERROR:
      jj_consume_token(ERROR);
                        info = op.parseError(cmd.substring(7, cmd.length()-1));
      break;
    case SCORE:
      jj_consume_token(SCORE);
                        info = op.parseScore(cmd.substring(7, cmd.length()-1));
      break;
    case OK:
      jj_consume_token(OK);
                     info = op.parseOk(cmd.substring(4, cmd.length()-1));
      break;
    default:
      jj_la1[3] = jj_gen;
      jj_consume_token(-1);
      throw new ParseException();
    }
  }

  final public void unknown() throws ParseException {
    label_1:
    while (true) {
      jj_consume_token(CHR);
      switch (jj_nt.kind) {
      case CHR:
        ;
        break;
      default:
        jj_la1[4] = jj_gen;
        break label_1;
      }
    }
                 System.out.println("unknown command: "+cmd);
  }

  public RobocupClientParserTokenManager token_source;
  SimpleCharStream jj_input_stream;
  public Token token, jj_nt;
  private int jj_gen;
  final private int[] jj_la1 = new int[5];
  static private int[] jj_la1_0;
  static {
      jj_la1_0();
   }
   private static void jj_la1_0() {
      jj_la1_0 = new int[] {0x40000,0x8fff0,0x380,0xf800,0x80000,};
   }

  public RobocupClientParser(java.io.InputStream stream) {
     this(stream, null);
  }
  public RobocupClientParser(java.io.InputStream stream, String encoding) {
    try { jj_input_stream = new SimpleCharStream(stream, encoding, 1, 1); } catch(java.io.UnsupportedEncodingException e) { throw new RuntimeException(e); }
    token_source = new RobocupClientParserTokenManager(jj_input_stream);
    token = new Token();
    token.next = jj_nt = token_source.getNextToken();
    jj_gen = 0;
    for (int i = 0; i < 5; i++) jj_la1[i] = -1;
  }

  public void ReInit(java.io.InputStream stream) {
     ReInit(stream);
  }
  public void ReInit(java.io.InputStream stream, String encoding) {
    try { jj_input_stream.ReInit(stream, encoding, 1, 1); } catch(java.io.UnsupportedEncodingException e) { throw new RuntimeException(e); }
    token_source.ReInit(jj_input_stream);
    token = new Token();
    token.next = jj_nt = token_source.getNextToken();
    jj_gen = 0;
    for (int i = 0; i < 5; i++) jj_la1[i] = -1;
  }

  public RobocupClientParser(java.io.Reader stream) {
    jj_input_stream = new SimpleCharStream(stream, 1, 1);
    token_source = new RobocupClientParserTokenManager(jj_input_stream);
    token = new Token();
    token.next = jj_nt = token_source.getNextToken();
    jj_gen = 0;
    for (int i = 0; i < 5; i++) jj_la1[i] = -1;
  }

  public void ReInit(java.io.Reader stream) {
    jj_input_stream.ReInit(stream, 1, 1);
    token_source.ReInit(jj_input_stream);
    token = new Token();
    token.next = jj_nt = token_source.getNextToken();
    jj_gen = 0;
    for (int i = 0; i < 5; i++) jj_la1[i] = -1;
  }

  public RobocupClientParser(RobocupClientParserTokenManager tm) {
    token_source = tm;
    token = new Token();
    token.next = jj_nt = token_source.getNextToken();
    jj_gen = 0;
    for (int i = 0; i < 5; i++) jj_la1[i] = -1;
  }

  public void ReInit(RobocupClientParserTokenManager tm) {
    token_source = tm;
    token = new Token();
    token.next = jj_nt = token_source.getNextToken();
    jj_gen = 0;
    for (int i = 0; i < 5; i++) jj_la1[i] = -1;
  }

  final private Token jj_consume_token(int kind) throws ParseException {
    Token oldToken = token;
    if ((token = jj_nt).next != null) jj_nt = jj_nt.next;
    else jj_nt = jj_nt.next = token_source.getNextToken();
    if (token.kind == kind) {
      jj_gen++;
      return token;
    }
    jj_nt = token;
    token = oldToken;
    jj_kind = kind;
    throw generateParseException();
  }

  final public Token getNextToken() {
    if ((token = jj_nt).next != null) jj_nt = jj_nt.next;
    else jj_nt = jj_nt.next = token_source.getNextToken();
    jj_gen++;
    return token;
  }

  final public Token getToken(int index) {
    Token t = token;
    for (int i = 0; i < index; i++) {
      if (t.next != null) t = t.next;
      else t = t.next = token_source.getNextToken();
    }
    return t;
  }

  private java.util.Vector jj_expentries = new java.util.Vector();
  private int[] jj_expentry;
  private int jj_kind = -1;

  public ParseException generateParseException() {
    jj_expentries.removeAllElements();
    boolean[] la1tokens = new boolean[20];
    for (int i = 0; i < 20; i++) {
      la1tokens[i] = false;
    }
    if (jj_kind >= 0) {
      la1tokens[jj_kind] = true;
      jj_kind = -1;
    }
    for (int i = 0; i < 5; i++) {
      if (jj_la1[i] == jj_gen) {
        for (int j = 0; j < 32; j++) {
          if ((jj_la1_0[i] & (1<<j)) != 0) {
            la1tokens[j] = true;
          }
        }
      }
    }
    for (int i = 0; i < 20; i++) {
      if (la1tokens[i]) {
        jj_expentry = new int[1];
        jj_expentry[0] = i;
        jj_expentries.addElement(jj_expentry);
      }
    }
    int[][] exptokseq = new int[jj_expentries.size()][];
    for (int i = 0; i < jj_expentries.size(); i++) {
      exptokseq[i] = (int[])jj_expentries.elementAt(i);
    }
    return new ParseException(token, exptokseq, tokenImage);
  }

  final public void enable_tracing() {
  }

  final public void disable_tracing() {
  }

}
